package com.stars.easyms.demo.service;

import com.stars.easyms.datasource.transaction.EasyMsDataSourceTransactionManager;
import com.stars.easyms.demo.dao.TestDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

/**
 * <p>className: TestService</p>
 * <p>description: </p>
 *
 * @author
 * @date 2019-05-08 17:46
 */
@Service
public class TestProgrammaticService {

    @Autowired
    private TestDAO testDAO;

    // 若没有自己项目中创建的PlatformTransactionManager的bean时，可以直接使用PlatformTransactionManager，否则使用EasyMsDataSourceTransactionManager
    @Autowired
    private PlatformTransactionManager transactionManager;

    //private final PlatformTransactionManager transactionManager = new EasyMsDataSourceTransactionManager();

    public void insertWithTransaction() {
        // 创建事务
        TransactionStatus transactionStatus =
                transactionManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW));

        try {
            // 执行插入默认数据源的主库
            testDAO.insertData_test_master();

            // 执行嵌套事务1方法
            this.insertWithNestedTransaction1();

            // 执行嵌套事务2方法
            this.insertWithNestedTransaction2();

            // 再执行插入other2的主库
            testDAO.insertData_other2_master();
        } catch (Exception e) {
            // 若有异常执行回滚，然后把异常抛出
            transactionManager.rollback(transactionStatus);
            throw e;
        }

        // 无异常，正常提交事务
        transactionManager.commit(transactionStatus);
    }

    /**
     * 创建嵌套事务1
     */
    private void insertWithNestedTransaction1() {
        TransactionStatus transactionStatus1 =
                transactionManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
        try {
            testDAO.insertData_other1_master();
            testDAO.insertData_test_master();
        } catch (Exception e) {
            transactionManager.rollback(transactionStatus1);
            throw e;
        }
        transactionManager.commit(transactionStatus1);
    }

    /**
     * 创建嵌套事务2
     */
    private void insertWithNestedTransaction2() {
        TransactionStatus transactionStatus2 =
                transactionManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_NOT_SUPPORTED));
        try {
            testDAO.insertData_other2_master();
            testDAO.insertData_test_master();
            testDAO.insertData_other1_master();
        } catch (Exception e) {
            transactionManager.rollback(transactionStatus2);
            throw e;
        }
        transactionManager.commit(transactionStatus2);
    }

}